package com.rich.richnative

import android.content.ContentValues
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.view.View
import android.view.animation.LinearInterpolator
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatImageView
import androidx.camera.core.Camera
import androidx.camera.core.CameraSelector
import androidx.camera.core.FocusMeteringAction
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.CircleCrop
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.text.SimpleDateFormat
import java.util.Locale


class RichnativeMainA : AppCompatActivity() {
    val rich_native_switch by lazy { findViewById<AppCompatImageView>(R.id.rich_native_switch) }
    val rich_native_switch_zoom by lazy { findViewById<LinearLayout>(R.id.rich_native_switch_zoom) }
    val rich_native_preview by lazy { findViewById<PreviewView>(R.id.rich_native_preview) }
    val rich_native_take by lazy { findViewById<View>(R.id.rich_native_take) }
    val rich_native_tv_zoom_1 by lazy { findViewById<TextView>(R.id.rich_native_tv_zoom_1) }
    val rich_native_tv_zoom_2 by lazy { findViewById<TextView>(R.id.rich_native_tv_zoom_2) }
    val rich_native_cap by lazy { findViewById<ImageView>(R.id.rich_native_cap) }

    private val rich_native_format = "yyyy-MM-dd-HH-mm-ss-SSS"

    private var rich_native_iCapture: ImageCapture? = null

    private var rich_native_cP: ProcessCameraProvider? = null

    private val rich_native_request_code = 10000

    private var rich_native_camera: Camera? = null

    private var rich_native_isBack = false
    private var rich_native_zoom_2 = false
    private var rich_native_ro = 1
    private val rich_native_rPs =
        mutableListOf(
            android.Manifest.permission.CAMERA,
//            android.Manifest.permission.RECORD_AUDIO
        ).apply {
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
                add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
            }
        }.toTypedArray()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        rich_native_full_ui(window)
        setContentView(R.layout.a_rich_native_main)

        rich_native_init_c()

        onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                MaterialAlertDialogBuilder(this@RichnativeMainA)
                    .setMessage("Exit ${resources.getString(R.string.rich_native_app_name)}?")
                    .setPositiveButton("YES") { _, _ ->
                        finish()
                    }
                    .show()
            }
        })

        rich_native_switch.setOnClickListener {

            rich_native_toggle_camera(rich_native_isBack)
        }

        rich_native_take.setOnClickListener {
            rich_native_init_c()
            rich_native_tP()
        }

        rich_native_preview.setOnTouchListener { _, event ->

            FocusMeteringAction.Builder(
                rich_native_preview.meteringPointFactory.createPoint(event.x, event.y)
            ).build().let {
                rich_native_show_focus(event.x.toInt(), event.y.toInt())
                rich_native_camera?.cameraControl?.startFocusAndMetering(it)
            }
            true
        }

        rich_native_switch_zoom.setOnClickListener {
            rich_native_zoom_2 = !rich_native_zoom_2
            rich_native_zoom(rich_native_zoom_2)
        }

        rich_native_cap.setOnClickListener {
//            val intent = Intent(Intent.ACTION_PICK, null)
//            intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*")
//            startActivity(intent)
            startActivity(Intent().apply {
                action = Intent.ACTION_MAIN
                addCategory(Intent.CATEGORY_APP_GALLERY)
            })
        }

    }

    private fun rich_native_zoom_ui(rich_native_zoom_2: Boolean) {
        if (!rich_native_zoom_2) {
            rich_native_tv_zoom_1.setTextColor(resources.getColor(R.color.rich_native_black))
            rich_native_tv_zoom_1.background =
                resources.getDrawable(R.drawable.rich_native_zoom_bg_1)
            rich_native_tv_zoom_2.setTextColor(resources.getColor(R.color.rich_native_white))
            rich_native_tv_zoom_2.background = null
        } else {
            rich_native_tv_zoom_1.setTextColor(resources.getColor(R.color.rich_native_white))
            rich_native_tv_zoom_1.background = null
            rich_native_tv_zoom_2.setTextColor(resources.getColor(R.color.rich_native_black))
            rich_native_tv_zoom_2.background =
                resources.getDrawable(R.drawable.rich_native_zoom_bg_1)
        }
    }

    private fun rich_native_zoom(rich_native_zoom_2: Boolean) {
        rich_native_camera?.cameraInfo?.zoomState?.value?.apply {
            val delta = if (rich_native_zoom_2) 2F else 0.5F
            rich_native_camera?.cameraControl?.setZoomRatio(this.zoomRatio * delta)
            rich_native_zoom_ui(rich_native_zoom_2)
        }
    }

    override fun onResume() {
        super.onResume()
        rich_native_zoom(rich_native_zoom_2)
    }

    private fun rich_native_init_c() {
        if (rich_native_all_Granted()) {
            rich_native_sCa()
        } else {
            ActivityCompat.requestPermissions(
                this,
                rich_native_rPs,
                rich_native_request_code
            )
        }
    }

    private fun rich_native_reset() {

    }

    override fun onDestroy() {
        super.onDestroy()
        rich_native_reset()
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        if (requestCode == rich_native_request_code) {
            if (rich_native_all_Granted()) {
                rich_native_sCa()
            } else {
                Toast.makeText(
                    baseContext,
                    "Permissions not granted by the user.",
                    Toast.LENGTH_SHORT
                ).show()
            }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }

    private fun rich_native_all_Granted() = rich_native_rPs.all {
        ContextCompat.checkSelfPermission(
            baseContext, it
        ) == PackageManager.PERMISSION_GRANTED
    }

    private fun rich_native_sCa() {
        if (rich_native_iCapture == null) {
            rich_native_iCapture =
                ImageCapture.Builder()
                    .build()
            ProcessCameraProvider.getInstance(this).also {
                it.addListener({
                    rich_native_cP = it.get()
                    rich_native_toggle_camera(false)
                }, ContextCompat.getMainExecutor(this@RichnativeMainA))
            }
        }
    }

    private fun rich_native_toggle_camera(isFront: Boolean) {
        try {
            rich_native_cP?.apply {
                rich_native_isBack = !rich_native_isBack
                rich_native_switch.animate().apply {
                    rotationY(180f * rich_native_ro++)
                    duration = 600
                    interpolator = LinearInterpolator()
                }.start()
                val preview = Preview.Builder().build().apply {
                    setSurfaceProvider(rich_native_preview.surfaceProvider)
                }

                unbindAll()
                CameraSelector.Builder()
                    .requireLensFacing(if (isFront) CameraSelector.LENS_FACING_FRONT else CameraSelector.LENS_FACING_BACK)
                    .build()
                    .let {
                        rich_native_camera = bindToLifecycle(
                            this@RichnativeMainA,
                            it,
                            preview,
                            rich_native_iCapture
                        )
                        rich_native_zoom_2 = false
                        rich_native_zoom_ui(rich_native_zoom_2)
                    }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun rich_native_tP() {
        rich_native_iCapture?.apply {
            val rich_native_filename = SimpleDateFormat(rich_native_format, Locale.US)
                .format(System.currentTimeMillis())
            val rich_native_config = ContentValues().apply {
                put(MediaStore.MediaColumns.DISPLAY_NAME, rich_native_filename)
                put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
                    put(
                        MediaStore.Images.Media.RELATIVE_PATH,
                        "Pictures/${resources.getString(R.string.rich_native_app_name)}"
                    )
                }
            }

            val rich_native_outOpt = ImageCapture.OutputFileOptions
                .Builder(
                    contentResolver,
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    rich_native_config
                )
                .build()

            takePicture(
                rich_native_outOpt,
                ContextCompat.getMainExecutor(this@RichnativeMainA),
                object : ImageCapture.OnImageSavedCallback {
                    override fun onError(exc: ImageCaptureException) {
                        Toast.makeText(baseContext, exc.localizedMessage, Toast.LENGTH_SHORT).show()
                    }

                    override fun onImageSaved(output: ImageCapture.OutputFileResults) {
                        Glide.with(this@RichnativeMainA)
                            .load(output.savedUri)
                            .transform(CircleCrop())
                            .into(rich_native_cap)
                    }
                }
            )
        }
    }

    private fun rich_native_show_focus(x: Int, y: Int) {
//        PopupWindow(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
//            .apply {
//                contentView = ImageView(this@RichnativeMainA).also {
//                    it.setImageResource(R.drawable.rich_native_focus)
//                }
//                showAsDropDown(rich_native_preview, x, y,Gravity.CENTER)
//                rich_native_preview.postDelayed({
//                    dismiss()
//                }, 300)
//                rich_native_preview.playSoundEffect(SoundEffectConstants.CLICK)
//            }
    }
}